from __future__ import annotations
import requests
from typing import Tuple, Any

GEOCODE_URL = "https://geocoding-api.open-meteo.com/v1/search"
FORECAST_URL = "https://api.open-meteo.com/v1/forecast"


def geocode_city(city_name: str) -> Tuple[float, float, str]:
    """通过城市名获取经纬度与标准化名称。"""
    params = {
        "name": city_name,
        "count": 1,
        "language": "zh",
        "format": "json",
    }
    resp = requests.get(GEOCODE_URL, params=params, timeout=10)
    resp.raise_for_status()
    data = resp.json()
    results = data.get("results") or []
    print(results)

    if not results:
        raise ValueError(f"无法找到城市: {city_name}")
    item = results[0]
    lat = float(item["latitude"])  # type: ignore[index]
    lon = float(item["longitude"])  # type: ignore[index]
    name = str(item.get("name"))
    admin1 = item.get("admin1")
    country = item.get("country")
    display_name = " ".join([x for x in [name, admin1, country] if x])
    return lat, lon, display_name


WEATHER_CODE_MAP = {
    0: "晴朗",
    1: "大致晴朗",
    2: "多云",
    3: "阴",
    45: "雾",
    48: "雾（沉积）",
    51: "毛毛雨（轻）",
    53: "毛毛雨（中）",
    55: "毛毛雨（强）",
    61: "小雨",
    63: "中雨",
    65: "大雨",
    66: "冻雨（轻）",
    67: "冻雨（强）",
    71: "小雪",
    73: "中雪",
    75: "大雪",
    77: "雪粒",
    80: "阵雨（轻）",
    81: "阵雨（中）",
    82: "阵雨（强）",
    85: "阵雪（轻）",
    86: "阵雪（强）",
    95: "雷暴",
    96: "雷暴伴冰雹（轻/中）",
    99: "雷暴伴冰雹（强）",
}


def fetch_today_daily(lat: float, lon: float, timezone: str) -> dict[str, Any]:
    params = {
        "latitude": lat,
        "longitude": lon,
        "daily": [
            "weathercode",
            "temperature_2m_max",
            "temperature_2m_min",
            "precipitation_probability_max",
        ],
        "timezone": timezone,
    }
    resp = requests.get(FORECAST_URL, params=params, timeout=15)
    resp.raise_for_status()
    data = resp.json()
    daily = data.get("daily") or {}

    def pick_first(key: str, default=None):
        arr = daily.get(key) or []
        return arr[0] if arr else default

    weathercode = int(pick_first("weathercode", -1))
    weather_text = WEATHER_CODE_MAP.get(weathercode, f"未知天气代码 {weathercode}")
    t_max = pick_first("temperature_2m_max")
    t_min = pick_first("temperature_2m_min")
    precip = pick_first("precipitation_probability_max")
    date_str = pick_first("time", "今天")

    return {
        "date": date_str,
        "weather_text": weather_text,
        "t_max": t_max,
        "t_min": t_min,
        "precip_probability_max": precip,
    }


def build_email_body(city_display: str, forecast: dict[str, Any]) -> str:
    lines = [
        f"{forecast['date']} {city_display} 天气提醒",
        f"天气：{forecast['weather_text']}",
        f"温度：{forecast['t_min']}°C ~ {forecast['t_max']}°C",
        f"降水概率（最大）：{forecast['precip_probability_max']}%",
        "\n祝你今天心情舒畅，出行顺利！",
    ]
    return "\n".join(lines)